bitkeeper revision 1.1677 (42a312b3NoXLv1fa_qVHaQXgt_JhLw)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sun, 5 Jun 2005 14:56:51 +0000 (14:56 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sun, 5 Jun 2005 14:56:51 +0000 (14:56 +0000)
Fix smp_call_function race (introduced a couple of days ago).
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/smp.c

index 5a8f6de6f08c1ac5acc3db62e727d0a2a50e6b4f..b0782ec5d77728f27dc243c6161b11fa75198752 100644 (file)
@@ -272,6 +272,7 @@ void smp_send_event_check_mask(cpumask_t mask)
 struct call_data_struct {
     void (*func) (void *info);
     void *info;
+    int wait;
     atomic_t started;
     atomic_t finished;
 };
@@ -299,6 +300,7 @@ int smp_call_function(
 
     data.func = func;
     data.info = info;
+    data.wait = wait;
     atomic_set(&data.started, 0);
     atomic_set(&data.finished, 0);
 
@@ -345,17 +347,22 @@ asmlinkage void smp_event_check_interrupt(void)
 
 asmlinkage void smp_call_function_interrupt(void)
 {
-    void (*func) (void *info) = call_data->func;
+    void (*func)(void *info) = call_data->func;
     void *info = call_data->info;
 
     ack_APIC_irq();
     perfc_incrc(ipis);
 
-    mb();
-    atomic_inc(&call_data->started);
-
-    (*func)(info);
-
-    mb();
-    atomic_inc(&call_data->finished);
+    if ( call_data->wait )
+    {
+        (*func)(info);
+        mb();
+        atomic_inc(&call_data->finished);
+    }
+    else
+    {
+        mb();
+        atomic_inc(&call_data->started);
+        (*func)(info);
+    }
 }